package com.kim.store.service.impl;

import com.kim.store.entity.Address;
import com.kim.store.mapper.AddressMapper;
import com.kim.store.service.IAddressService;
import com.kim.store.service.IDistrictService;
import com.kim.store.service.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 收货地址接口的实现类
 */
@Service
public class AddressServiceImpl implements IAddressService {
    @Autowired
    private AddressMapper addressMapper;
    //添加用户收货地址的业务层依赖于DistrictService业务层接口
    @Autowired
    private IDistrictService districtService;
    @Value("${user.address.max-count}")
    private Integer maxCount;

    /**
     * 在addNewAddress方法中将districtService接口中获取到的省市区数据转移到address对象，
     * 这个对象就包含了所有用户的收货地址的数据！！
     */
    @Override
    public void addNewAddress(Integer uid, String username, Address address) {
        //调用收获地址统计方法
        Integer count = addressMapper.countByUid(uid);
        if (count >= maxCount){
            throw new AddressCountLimitException("用户收获地址超出上限");
        }
        //对address对象中的数据进行补全：省市区
        //前端表单传递过来的是省市区的编号
        String provinceName = districtService.getNameByCode(address.getProvinceCode());
        String cityName = districtService.getNameByCode(address.getCityCode());
        String areaName = districtService.getNameByCode(address.getAreaCode());
        address.setProvinceName(provinceName);
        address.setCityName(cityName);
        address.setAreaName(areaName);

        //补全uid、isDefault
        address.setUid(uid);
        Integer isDefault = count == 0 ? 1 : 0; //1表示默认，0表示不是默认
        address.setIsDefault(isDefault);
        //补全4项日志
        address.setCreatedUser(username);
        address.setCreatedTime(new Date());
        address.setModifiedUser(username);
        address.setModifiedTime(new Date());
        //调用插入收获地址的方法
        Integer row = addressMapper.insert(address);
        if(row!=1){
            throw new InsertException("插入时产生未知异常");
        }
    }

    @Override
    public List<Address> getByUid(Integer uid) {
        List<Address> list = addressMapper.finByUid(uid);
        for (Address address : list) {
            //address.setAid(null);
            //address.setUid(null);
            address.setProvinceCode(null);
            address.setCityCode(null);
            address.setAreaCode(null);
            address.setTel(null);
            address.setIsDefault(null);
            address.setCreatedTime(null);
            address.setCreatedUser(null);
            address.setModifiedTime(null);
            address.setModifiedUser(null);

        }
        return list;
    }

    @Override
    public void setDefault(Integer aid, Integer uid, String username) {
        Address res = addressMapper.findByAid(aid);
        if(res == null){
            throw new AddressNotFoundException("收货地址不存在");
        }
        //检测当前获取到的收货地址数据的归属
        //res.getUid()的返回值是Integer，是个包装类，包装类都有equals方法
        if(!(res.getUid().equals(uid))){
            throw new AccessDeniedException("非法数据访问");
        }
        //先将所有的收货地址设置为非默认
        Integer row = addressMapper.updateNonDefault(uid);
        if(row<1){
            throw new UpdateException("更新时产生异常");
        }
        row = addressMapper.updateDefaultByAid(aid, username, new Date());
        if(row!=1){
            throw new UpdateException("更新时产生异常");
        }
    }

    @Override
    public void delete(Integer aid, Integer uid, String username) {
        Address res = addressMapper.findByAid(aid);
        if(res == null){
            throw  new AddressNotFoundException("收货地址数据不存在");
        }
        if(!(res.getUid().equals(uid))){
            throw new AccessDeniedException("非法数据访问");
        }
        //如果没有收货地址数据时
        Integer count = addressMapper.countByUid(uid);
        if(count == 0){
            //直接终止程序
            return;
        }

        //删除收货地址数据
        Integer row =  addressMapper.deleteByAid(aid);
        if(row != 1){
            throw new DeleteException("删除时产生未知异常");
        }

        // 如果删除的数据地址is_default==1时
        // 查询最新添加的收货地址数据，并把is_default改成1
        if (res.getIsDefault()==1){
            Address address = addressMapper.findLastModified(uid);
            Integer newAid = address.getAid();
            Integer rows = addressMapper.updateDefaultByAid(newAid, username, new Date());
            if(rows!=1){
                throw new UpdateException("更新数据时产生未知异常");
            }
        }


    }

    @Override
    public void changeAddressInfo(Integer aid,
                                  Integer uid,
                                  String username,
                                  Address address) {

        Address res = addressMapper.findByAid(aid);
        if(res == null){
            throw new AddressNotFoundException("收货地址数据不存在");
        }
        if(!(res.getUid().equals(uid))){
            throw new AccessDeniedException("非法数据访问");
        }
        //补全数据和去除无用数据
        address.setModifiedUser(username);
        address.setModifiedTime(new Date());
        address.setCreatedUser(null);
        address.setCreatedTime(null);

        //对address对象中的数据进行补全：省市区
        //前端表单传递过来的是省市区的编号
        String provinceName = districtService.getNameByCode(address.getProvinceCode());
        String cityName = districtService.getNameByCode(address.getCityCode());
        String areaName = districtService.getNameByCode(address.getAreaCode());
        address.setProvinceName(provinceName);
        address.setCityName(cityName);
        address.setAreaName(areaName);

        Integer row = addressMapper.updateAddressByAid(address);
        if (row!=1){
            throw new UpdateException("更新收获地址时产生未知异常");
        }
    }

    @Override
    public Address getByAid(Integer aid,Integer uid) {
        Address res = addressMapper.findByAid(aid);
        if(res==null){
            throw new AddressNotFoundException("用户收获地址不存在");
        }
        if(!(res.getUid().equals(uid))){
            throw new AccessDeniedException("非法访问数据");
        }
        return res;
    }
}
